<template>
  <div>
    <div class="upload-show-list" :class="[{'is-flex': !blockShow}]">
      <div class="upload-over-show" v-if="value">
        <show-item :file="value" @remove="removeUpload"/>
      </div>
      <div class="upload-button" @click="editCropper">
        <slot>
          <el-button type="primary" size="small" v-if="uploadType === 'button'"><i class="el-icon-upload2"></i> 点击上传</el-button>
          <div class="upload-button_box" v-else>
            <i class="el-icon-plus"></i>
          </div>
        </slot>
      </div>
    </div>

    <el-dialog :title="title" :visible.sync="open" class="dialog-md" append-to-body @opened="modalOpened" @close="closeDialog" >
      <el-row>
        <el-col :xs="24" :sm="12" :style="{height: '320px'}">
          <vue-cropper
            ref="cropper"
            v-bind="showOptions"
            @realTime="realTime"
            v-if="visible"
          />
        </el-col>
        <el-col :xs="24" :sm="12" :style="{height: '320px', position: 'relative'}">
          <div class="upload-preview">
            <div class="upload-preview_box" :style="previewStyle">
              <img :src="previews.url" :style="previews.img"/>
            </div>
          </div>
        </el-col>
      </el-row>
      <div class="footer-container">
        <div class="footer-left">
          <el-upload class="choose-uploader" action="#" :http-request="requestUpload" :show-file-list="false" :before-upload="beforeUpload">
            <el-button size="small" plain type="primary">选择<i class="el-icon-upload el-icon--right"></i></el-button>
          </el-upload>
          <el-button icon="el-icon-plus" size="small" @click="changeScale(1)"></el-button>
          <el-button icon="el-icon-minus" size="small" @click="changeScale(-1)"></el-button>
          <el-button icon="el-icon-refresh-left" size="small" @click="rotateLeft()"></el-button>
          <el-button icon="el-icon-refresh-right" size="small" @click="rotateRight()"></el-button>
          <el-button icon="el-icon-refresh" size="small" @click="refresh()"></el-button>
        </div>
        <div class="footer-right">
          <el-button type="primary" size="small" @click="uploadImg()">提 交</el-button>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { VueCropper } from 'vue-cropper'
import ShowItem from './ShowItem'
import { UPLOADER } from '@/config'
import request from '@/utils/request'
import { getFileName } from '@/utils/tools/url'

export default {
  components: { VueCropper, ShowItem },
  props: {
    value: {
      type: String,
      default: ''
    },  // 同步值
    title: {
      type: String,
      default: '裁剪上传图片'
    },
    uploadType: {
      type: String,
      default: 'button',
    },
    blockShow: Boolean,
    extraData: Object, // 上传额外操作
    fixedBox: Boolean,
    fixed: Boolean,
    fixedNumber: {
      type: Array,
      default: () => [1, 1]
    }
  },
  data() {
    return {
      open: false,  // 是否显示弹出层
      visible: false, // 是否显示cropper
      options: {
        img: '',  //裁剪图片的地址
        autoCrop: true,             // 是否默认生成截图框
        autoCropWidth: 200,         // 默认生成截图框宽度
        autoCropHeight: 200,        // 默认生成截图框高度
        info: true,                 // 裁剪框的大小信息
        canScale: true,             // 是否允许滚轮缩放
        fixedBox: false,            // 固定截图框大小
        fixed: false,               // 是否开启截图框宽高固定比例
        fixedNumber: [1, 1],        // 截图框的宽高比例
        canMove: true,              // 图片是否可以移动
        canMoveBox: true,           // 截图框能否拖动
        original: false,            // 上传图片按照原始比例渲染
        centerBox: false,           // 截图框是否被限制在图片里面
        limitMinSize: 10,           //裁剪框限制最小区域
        outputType: 'png',          // 默认生成截图为PNG格式
        filename: ''          // 文件名称
      },
      previews: {}
    }
  },
  watch: {
    value: {
      handler(val) {
        let url = val || ''
        this.options.img = this.staticUrl(url)
        this.options.filename = getFileName(url)
      },
      immediate: true
    }
  },
  computed: {
    previewStyle() {
      let w = this.previews.w || 0
      let h = this.previews.h || 0
      if (w <= 0 || h <= 0) return {}
      return { width: w + 'px', height: h + 'px', zoom: w / h > 1 ? 200 / w : 200 / h }
    },
    showOptions() {
      return {
        ...this.options, fixedBox: this.fixedBox, fixed: this.fixed, fixedNumber: this.fixedNumber
      }
    }
  },
  methods: {
    // 编辑头像
    editCropper() {
      this.open = true
    },
    // 打开弹出层结束时的回调
    modalOpened() {
      this.visible = true
    },
    // 覆盖默认的上传行为
    requestUpload() {
    },
    removeUpload() {
      this.$emit('input', '')
    },
    // 向左旋转
    rotateLeft() {
      this.$refs.cropper.rotateLeft()
    },
    // 刷新
    refresh() {
      this.$refs.cropper.refresh()
    },
    // 向右旋转
    rotateRight() {
      this.$refs.cropper.rotateRight()
    },
    // 图片缩放
    changeScale(num) {
      num = num || 1
      this.$refs.cropper.changeScale(num)
    },
    // 上传预处理
    beforeUpload(file) {
      if (file.type.indexOf('image/') === -1) {
        this.$modal.msgError('文件格式错误，请上传图片类型,如：JPG，PNG后缀的文件。')
      } else {
        const reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = () => {
          this.options.img = reader.result
          this.options.filename = file.name
        }
      }
    },
    // 上传图片
    uploadImg() {
      this.$refs.cropper.getCropBlob(data => {
        let formData = new FormData()
        formData.append('file', data, this.options.filename + '.' + this.options.outputType)
        if (this.extraData) {
          for (let i in this.extraData) {
            formData.append(i, this.extraData[i])
          }
        }
        request.upload(UPLOADER.IMAGE, formData).then(res => {
          this.$emit('input', res.path)
          this.open = false
          this.visible = false
        })
      })
    },
    // 实时预览
    realTime(data) {
      this.previews = data
    },
    // 关闭窗口
    closeDialog() {
      this.visible = false
    }
  }
}
</script>
<style scoped lang="scss">
.upload-over-show {
  width: 100px;
  height: 100px;
  position: relative;
  margin-right: 10px;
}
.upload-show-list {
  display: flex;
  flex-direction: column;
  align-items: center;
  &.is-flex {
    flex-direction: row;
  }
}
.upload-button_box {
  width: 100px;
  height: 100px;
  border: 1px dashed #c0ccda;
  border-radius: 6px;
  cursor: pointer;
  vertical-align: top;
  background-color: #fbfdff;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;

  i {
    font-size: 28px;
    color: #8c939d;
  }

  &:hover {
    border-color: #1890FF;
  }
}

.upload-preview {
  position: relative;
  width: 200px;
  height: 200px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  overflow: hidden;
  border: 1px solid #ccc;
  display: flex;
  align-items: center;
  justify-content: center;

  &_box {
    width: 0;
    height: 0;
    overflow: hidden;
    margin: 0;
  }
}


.footer-container {
  display: flex;
  flex-wrap: wrap;
  .footer-left {
    display: flex;
    flex-wrap: wrap;
    flex-shrink: 0;
    margin-right: 10px;
    margin-top: 10px;
    .choose-uploader {
      margin-right: 10px;
    }
  }
  .footer-right {
    margin-top: 10px;
    flex-grow: 1;
    text-align: center;
  }
}
</style>
